﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;
using PokeData;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PokeTD
{
    /// <summary>
    /// Klasse für Creeps
    /// </summary>
    public class Creep
    {
        /// <summary>
        /// Event-Handler für das Sterben eines Creeps
        /// </summary>
        public event CreepEventHandler OnCreepDeath;

        public event CreepEventHandler OnCreepSave;

        /// <summary>
        /// Properties
        /// </summary>
        private string _Name;

        private string _ImgPath; // Pfad nicht direkt, eher den Dateinamen ohne Endung

        // Stats
        private int _HP;
        private int _MaxHP;

        private int _DefPhys;
        private int _DefSpez;
        private int _Speed;
        private bool _isFlying;

        private Typ _Typ1;
        private Typ _Typ2;

        private bool _isSpawned;

        private Vector2 _Position;

        private bool _isDead = false;
        private bool _isStunned = false;
        private bool _isSlowed = false;

        private int _moneyPerKill;

        //Die aktuelle Richtung, in die das Creep geht - dafür gibts den Enum Direction!
        private Direction _Direction;
        private List<Vector2> _path;

        // Manche Creeps können neue Spawnen, wenn sie zerstört wurden.
        private int _SpawnCount;  // = Anzahl
        private int _SpawnID;     // = Typ

        private float _animationcounter = 0;



        /// <summary>
        /// Getter und Setter für die Properties
        /// </summary>
        public string Name {
            get { return _Name; }
        }

        public string ImgPath {
            get { return _ImgPath; }
            set { _ImgPath = value; }
        }

        public int HP
        {
            get { 
                return _HP; 
            }
            set {
                if (value <= 0) {
                    _HP = 0;
                    this.isDead = true;
                    OnCreepDeath(this, new CreepEventArgs());
                }
                else {
                    _HP = value;
                }
            }
        }
        public int MaxHP {
            get { return _MaxHP; }
        }
        public int DefPhys {
            get { return _DefPhys; }
        }
        public int DefSpez {
            get { return _DefSpez; }
        }
        public int Speed {
            get {
                if (isStunned) return 0;
                if (isSlowed) return _Speed / 2;
                return _Speed;
            }
        }
        public bool isFlying {
            get { return _isFlying; }
        }

        public Typ Typ1 {
            get { return _Typ1; }
        }
        public Typ Typ2 {
            get { return _Typ2; }
        }

        public bool isSpawned {
            get { return _isSpawned; }
            set { _isSpawned = value; }
        }

        public Vector2 Position {
            get { return _Position; }
            set { _Position = value; }
        }
        public int X
        {
            get
            {
                return (int)Position.X;
            }
            set
            {
                _Position.X = value;
            }
        }
        public int Y
        {
            get
            {
                return (int)Position.Y;
            }
            set
            {
                _Position.Y = value;
            }
        }
        public Vector2 Center {
            get { return _Position + new Vector2(Block.BlockWidth / 2, Block.BlockHeight / 2); }
        }
        public bool isDead {
            get { return _isDead; }
            set { _isDead = value; }
        }
        public bool isStunned {
            get { return _isStunned; }
            set { _isStunned = value; }
        }
        public bool isSlowed {
            get { return _isSlowed; }
            set { _isSlowed = value; }
        }

        public Direction Direction {
            get { return _Direction; }
            set { _Direction = value; }
        }
        public List<Vector2> Path {
            get { return _path; }
            set { _path = new List<Vector2>(); foreach (Vector2 b in value) _path.Add(b); }
        }

        public int SpawnCount {
            get { return _SpawnCount; }
            set { _SpawnCount = value; }
        }
        public int SpawnID {
            get { return _SpawnID; }
            set { _SpawnID = value; }
        }
        public int MoneyPerKill
        {
            get { return _moneyPerKill; }
            set { _moneyPerKill = value; }
        }

        public float AnimationCounter {
            get { return _animationcounter; }
            set { _animationcounter = value; }
        }
        /// <summary>
        /// Lädt einen Creep aus der Datenbak
        /// </summary>
        /// <param name="CID">Creep-ID</param>
        public Creep(int CID)
        {
            IEnumerable<DataRow> q = from s in Globals.waveDS.Creeps
                where s.id == CID
                select s;
            DataRow CreepRow = q.First();
            assignData((string)CreepRow["CreepName"], (string)CreepRow["ImgPath"], (int)CreepRow["HP"], (int)CreepRow["PhysVert"], (int)CreepRow["SpVert"], (int)CreepRow["MovementSpeed"], (bool)CreepRow["flying"], (Typ)CreepRow["type1"], (Typ)CreepRow["type2"], 0, 0, (int)CreepRow["MoneyPerKill"]);
        }

        /// <summary>
        /// Konstruktor zum generieren von neuen Creeps (ohne Spawn-Fähigkeit)
        /// </summary>
        /// <param name="Name">Name</param>
        /// <param name="ImgPath">Pfad zum BIld</param>
        /// <param name="HP">Anzahl HP</param>
        /// <param name="DefPhys">Wert für physische Verteidigung</param>
        /// <param name="DefSpez">Wert für spezielle Verteidigung</param>
        /// <param name="Speed">Geschwindigkeit des Creeps</param>
        /// <param name="Flying">Fliegender Creep?</param>
        /// <param name="Typ1">Typ1 des Creeps</param>
        /// <param name="Typ2">Typ2 des Creeps</param>
        /// <param name="mpk">Geld, das der Spieler für das Töten des Creeps erhält</param>
        public Creep(string Name, string ImgPath, int HP, int DefPhys, int DefSpez, int Speed, bool Flying, Typ Typ1, Typ Typ2, int mpk) {
            assignData(Name, ImgPath, HP, DefPhys, DefSpez, Speed, Flying, Typ1, Typ2, 0, 0, mpk);
        }

        /// <summary>
        /// Konstruktor zum generieren von neuen Creeps
        /// </summary>
        /// <param name="Name">Name</param>
        /// <param name="ImgPath">Pfad zum BIld</param>
        /// <param name="HP">Anzahl HP</param>
        /// <param name="DefPhys">Wert für physische Verteidigung</param>
        /// <param name="DefSpez">Wert für spezielle Verteidigung</param>
        /// <param name="Speed">Geschwindigkeit des Creeps</param>
        /// <param name="Flying">Fliegender Creep?</param>
        /// <param name="Typ1">Typ1 des Creeps</param>
        /// <param name="Typ2">Typ2 des Creeps</param>
        /// <param name="SpawnCount">Anzahl der zu spawnenden Creeps nach Tod</param>
        /// <param name="SpawnID">ID der Spawn-Creeps</param>
        /// <param name="mpk">Geld, das der Spieler für das Töten des Creeps erhält</param>
        public Creep(string Name, string ImgPath, int HP, int DefPhys, int DefSpez, int Speed, bool Flying, Typ Typ1, Typ Typ2, int SpawnCount, int SpawnID, int mpk) { 
            assignData(Name, ImgPath, HP, DefPhys, DefSpez, Speed, Flying, Typ1, Typ2, SpawnCount, SpawnID, mpk);
        }

        private void assignData(string Name, string ImgPath, int HP, int DefPhys, int DefSpez, int Speed, bool Flying, Typ Typ1, Typ Typ2, int SpawnCount, int SpawnID, int mpk) {
            _Name = Name;
            _ImgPath = ImgPath;
            _HP = HP;
            _MaxHP = HP;
            _DefPhys = DefPhys;
            _DefSpez = DefSpez;
            _Speed = Speed;
            _isFlying = Flying;
            _Typ1 = Typ1;
            _Typ2 = Typ2;
            _SpawnCount = SpawnCount;
            _SpawnID = SpawnID;
            _moneyPerKill = mpk;
        }
    }
}
